package com.hy.usercenter.jobs;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hy.usercenter.model.domain.SysUser;
import com.hy.usercenter.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.hy.usercenter.constants.UserConstant.KEY_PREFIX;

/**
 * @Description 缓存预热，把部分用户的推荐数据提前加载到缓存里，使用户始终请求很快
 *
 * @Author minsf
 * @Date 2023/2/24
 */
@Component
@Slf4j
public class CachePreLoadJob {

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private SysUserService sysUserService;

    private List<Integer> mainList = Arrays.asList(1, 2, 3);

    @Scheduled(cron = "0 54 22 * * *")
    public void preLoadUserData() {
        // 设置分布式锁key
        RLock lock = redissonClient.getLock("user-center-user-preLoadData");

        try {
            if (lock.tryLock(0, 30000L, TimeUnit.MILLISECONDS)) {
                log.info(Thread.currentThread().getName()+" 抢到了锁，并开始执行任务");
                // 业务逻辑处理
                mainList.forEach(id -> {
                    ValueOperations<String, Object> operations = redisTemplate.opsForValue();
                    LambdaQueryWrapper<SysUser> lqw = Wrappers.lambdaQuery();
                    List<SysUser> result = sysUserService.list(lqw);

                    operations.set(KEY_PREFIX + id, result, 90, TimeUnit.SECONDS);
                });

            }
        } catch (Exception e) {
            log.error("error occur:",e);
        } finally {
            // 判断锁释放属于当前线程
            if (lock.isHeldByCurrentThread()) {
                // 释放锁
                log.info(Thread.currentThread().getName()+" 释放了锁，并执行完成了任务");
                lock.unlock();
            }
        }

    }
}
